home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / dejagnu.lha / dejagnu-1.0.1 / expect / pty_sgttyb.c < prev    next >
C/C++ Source or Header  |  1993-03-29  |  6KB  |  223 lines

  1. /* pty_bsd.c - routines to allocate ptys - BSD version
  2.  
  3. Written by: Don Libes, NIST, 2/6/90
  4.  
  5. Design and implementation of this program was paid for by U.S. tax
  6. dollars.  Therefore it is public domain.  However, the author and NIST
  7. would appreciate credit if this program or parts of it are used.
  8.  
  9. */
  10.  
  11. #include <stdio.h>        /* tmp for debugging */
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. /*** #include <sys/ioctl.h> ***/
  15. #include <sys/file.h>
  16. #include <signal.h>
  17. #include <setjmp.h>
  18. #include <errno.h>
  19. #include "exp_conf.h"
  20. #include "exp_rename.h"
  21. #include "exp_tty.h"
  22. #include "exp_pty.h"
  23.  
  24. extern int errno;
  25.  
  26. #ifdef O_NOCTTY
  27. #define RDWR ((O_RDWR)|(O_NOCTTY))
  28. #else
  29. #define RDWR O_RDWR
  30. #endif
  31.  
  32. void debuglog();
  33.  
  34. #ifndef TRUE
  35. #define TRUE 1
  36. #define FALSE 0
  37. #endif
  38.  
  39. static char    master_name[] = "/dev/ptyXX";    /* master */
  40. static char     slave_name[] = "/dev/ttyXX";    /* slave */
  41. static char    *tty_type;        /* ptr to char [pt] denoting
  42.                        whether it is a pty or tty */
  43. static char    *tty_bank;        /* ptr to char [p-z] denoting
  44.                        which bank it is */
  45. static char    *tty_num;        /* ptr to char [0-f] denoting
  46.                        which number it is */
  47.  
  48. static void
  49. pty_stty(s,name)
  50. char *s;        /* args to stty */
  51. char *name;        /* name of pty */
  52. {
  53.     int cc;
  54.  
  55. #define MAX_ARGLIST 10240
  56.     char buf[MAX_ARGLIST];    /* overkill is easier */
  57.  
  58.     /* tell Saber to shut up over confusion of sprintf return type */
  59.     /*SUPPRESS 701*/
  60.     sprintf(buf,"stty %s < %s > %s",s,name,name);
  61.     debuglog("getptyslave: system(\"%s\") = ",buf);
  62.     cc = system(buf);
  63.     debuglog("%d\n",cc);
  64. }
  65.  
  66. struct sgttyb exp_tty_original;    /* tty parms that include raw/echo */
  67.  
  68. int dev_tty;        /* file descriptor to /dev/tty or -1 if none */
  69. int knew_dev_tty;    /* true if we had our hands on /dev/tty at any time */
  70.  
  71. #define GET_TTYTYPE    0
  72. #define SET_TTYTYPE    1
  73. static void
  74. ttytype(request,fd,ttycopy,ttyinit,s)
  75. int request;
  76. int fd;
  77.         /* following are used only if request == SET_TTYTYPE */
  78. int ttycopy;    /* if true, copy from /dev/tty */
  79. int ttyinit;    /* if true, initialize to sane state */
  80. char *s;    /* stty args */
  81. {
  82.     static struct    tchars tc;        /* special characters */
  83.     static struct    ltchars lc;        /* local special characters */
  84.     static struct    winsize win;        /* window size */
  85.     static int    lb;            /* local modes */
  86.     static int    l;            /* line discipline */
  87.  
  88.     if (request == GET_TTYTYPE) {
  89.         if (-1 == ioctl(fd, TIOCGETP, (char *)&exp_tty_original)
  90.          || -1 == ioctl(fd, TIOCGETC, (char *)&tc)
  91.          || -1 == ioctl(fd, TIOCGETD, (char *)&l)
  92.          || -1 == ioctl(fd, TIOCGLTC, (char *)&lc)
  93.          || -1 == ioctl(fd, TIOCLGET, (char *)&lb)
  94.          || -1 == ioctl(fd, TIOCGWINSZ, (char *)&win)) {
  95.             knew_dev_tty = FALSE;
  96.             dev_tty = -1;
  97.         }
  98.     } else {    /* type == SET_TTYTYPE */
  99.         if (ttycopy && knew_dev_tty) {
  100.             (void) ioctl(fd, TIOCSETP, (char *)&exp_tty_original);
  101.             (void) ioctl(fd, TIOCSETC, (char *)&tc);
  102.             (void) ioctl(fd, TIOCSLTC, (char *)&lc);
  103.             (void) ioctl(fd, TIOCLSET, (char *)&lb);
  104.             (void) ioctl(fd, TIOCSETD, (char *)&l);
  105.             (void) ioctl(fd, TIOCSWINSZ, (char *)&win);
  106.         }
  107.  
  108. #ifdef __SABER__
  109. #undef DFLT_STTY
  110. #define DFLT_STTY "sane"
  111. #endif
  112.         if (ttyinit) {
  113.             /* overlay parms originally supplied by Makefile */
  114.             debuglog("getptyslave: (default) stty %s\n",DFLT_STTY);
  115.             pty_stty(DFLT_STTY,slave_name);
  116.         }
  117.  
  118.         /* lastly, give user chance to override any terminal parms */
  119.         if (s) {
  120.             debuglog("getptyslave: (user-requested) stty %s\n",s);
  121.             pty_stty(s,slave_name);
  122.         }
  123.     }
  124. }
  125.  
  126. void
  127. init_pty()
  128. {
  129.     tty_type = & slave_name[strlen("/dev/")];
  130.     tty_bank = &master_name[strlen("/dev/pty")];
  131.     tty_num  = &master_name[strlen("/dev/ptyp")];
  132.  
  133.     dev_tty = open("/dev/tty",O_RDWR);
  134.  
  135. #if experimental
  136.     /* code to allocate force expect to get a controlling tty */
  137.     /* even if it doesn't start with one (i.e., under cron). */
  138.     /* This code is not necessary, but helpful for testing odd things. */
  139.     if (dev_tty == -1) {
  140.         /* give ourselves a controlling tty */
  141.         int master = getptymaster();
  142.         fcntl(master,F_SETFD,1);    /* close-on-exec */
  143.         setpgrp(0,0);
  144.         close(0);
  145.         close(1);
  146.         getptyslave(get_var("stty_init"));
  147.         close(2);
  148.         fcntl(0,F_DUPFD,2);        /* dup 0 onto 2 */
  149.     }
  150. #endif
  151.  
  152.     knew_dev_tty = (dev_tty != -1);
  153.     if (knew_dev_tty) ttytype(GET_TTYTYPE,dev_tty,0,0,(char *)0);
  154. }
  155.  
  156. /* returns fd of master end of pseudotty */
  157. int
  158. getptymaster()
  159. {
  160.     int master = -1;
  161.     char *hex, *bank;
  162.     struct stat statbuf;
  163.  
  164.     if (exp_pty_test_start() == -1) return -1;
  165.  
  166.     for (bank = "pqrstuvwxyzPQRSTUVWXYZ";*bank;bank++) {
  167.         *tty_bank = *bank;
  168.         *tty_num = '0';
  169.         if (stat(master_name, &statbuf) < 0) break;
  170.         for (hex = "0123456789abcdef";*hex;hex++) {
  171.             *tty_num = *hex;
  172.  
  173.             /* generate slave name from master */
  174.             strcpy(slave_name,master_name);
  175.             *tty_type = 't';
  176.  
  177.             master = exp_pty_test(master_name,slave_name,
  178.                         *tty_bank,*tty_num);
  179.             if (master >= 0) goto done;
  180.         }
  181.     }
  182.  done:
  183.     exp_pty_test_end();
  184.     return(master);
  185. }
  186.  
  187. int
  188. getptyslave(ttycopy,ttyinit,stty_args)
  189. int ttycopy;
  190. int ttyinit;
  191. char *stty_args;
  192. {
  193.     int slave;
  194.  
  195.     if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
  196.  
  197.     /* sanity check - if slave not 0, skip rest of this and return */
  198.     /* to what will later be detected as an error in caller */
  199.     if (0 != slave) return(slave);
  200.  
  201.     fcntl(0,F_DUPFD,1);    /* duplicate 0 onto 1 to prepare for stty */
  202.     ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
  203.     (void) exp_pty_unlock();
  204.     return(slave);
  205. }
  206.  
  207. #if 0
  208. opendevtty()
  209. {
  210.     int fd;
  211.     int p;
  212.  
  213.     errorlog("--opendevtty--\n");
  214.     errorlog("pid = %d\n",getpid());
  215.     errorlog("pgrp = %d\n",getpgrp(0));
  216.     ioctl(0,TIOCGPGRP,&p);
  217.     errorlog("tgrp(0) = %d\n",p);
  218.     if (-1 == (fd = open("/dev/tty",2))) {
  219.         perror("open"); errorlog("sanity open failed\n");
  220.     } else errorlog("sanity open succeeded\n");
  221. }
  222. #endif
  223.